<template>
    <div class="body">
        <section class="main-content">
            <h1 id="国密sm9基于身份的密码">国密SM9基于身份的密码</h1>

            <p>SM9是基于身份的密码，在国密SSL VPN规范中采用了基于SM9的密钥交换(IBSDH)和密钥传输(IBC)密码套件。</p>

            <h2 id="第2-部分数字签名算法">第2 部分：数字签名算法</h2>

            <h3 id="1-概述">1 概述</h3>

            <p>本部分规定了用椭圆曲线对实现的基于标识的数字签名算法，包括数字签名生成算法和验证算法，并给出了数字签名与验证算法及其相应的流程。</p>

            <h3 id="2-算法参数与辅助函数">2 算法参数与辅助函数</h3>

            <h4 id="21-概述">2.1 概述</h4>
            <p>
                本部分规定了一个用椭圆曲线对实现的基于标识的数字签名算法。该算法的签名者持有一个标识和一个相应的签名私钥，该签名私钥由密钥生成中心通过签名主私钥和签名者的标识结合产生。签名者用自身签名私钥对数据产生数字签名，验证者用签名者的标识验证签名的可靠性。</p>

            <p>在签名的生成和验证过程之前，都要用密码杂凑函数对待签消息M和待验证消息Mꞌ 进行压缩。</p>

            <h4 id="22-系统参数组">2.2 系统参数组</h4>
            <p>
                系统参数组包括曲线识别符$cid$；椭圆曲线基域$F_q$的参数；椭圆曲线方程参数$a$和$b$；扭曲线参数β(若$cid$的低4位为2)；曲线阶的素因子$N$和相对于$N$的余因子$cf$；曲线$E(F_q)$相对于$N
                $的嵌入次数k；$E(F_{q^{d_1}}$)( $d_1$ 整除k)的N阶循环子群$G_1$
                的生成元$P_1$；$E(F_{q^{d_2}}$)($d_2$整除k)的N阶循环子群$G_2$的生成元$P_2$；双线性对$e$ 的识别符$eid$；(选项) $G_2$到$G_1$
                的同态映射ψ。双线性对e
                的值域为N 阶乘法循环群$G_T$。</p>

            <h4 id="23-系统签名主密钥和用户签名密钥的产生">2.3 系统签名主密钥和用户签名密钥的产生</h4>

            <table>
                <tbody>
                <tr>
                    <td>
                        KGC产生随机数$ks∈[1,N−1]$作为签名主私钥，计算$G_2$的元素$P_{pub-s}=[ks]P_2$作为签名主公钥，则签名主密钥对为$(ks,P_{pub-s})$。KGC秘密保存$ks$，公开$P_{pub-s}$。KGC选择并公开用一个字节表示的签名私钥生成函数识别符hid。用户A的标识为$ID_A$，为产生用户A的签名私钥$d_{sA}$，KGC首先在有限域$F_N$上计算$t_1=H_1(ID_A
                    </td>
                    <td></td>
                    <td>hid,N)+ks$，若$t_1=0$则重新产生签名主私钥，计算和公开签名主公钥，并更新已有用户的签名私钥；否则计算</td>
                </tr>
                </tbody>
            </table>

            <p>$t_2 = ks · t_1^{-1}$ mod N，然后计算$ds_A=[t_2]P_1$。</p>

            <h4 id="24-辅助函数"><strong>2.4</strong> 辅助函数</h4>
            <h5 id="241-概述">2.4.1 概述</h5>
            <p>在本部分规定的基于标识的数字签名算法中，涉及到两类辅助函数：密码杂凑函数与随机数发生器。</p>
            <h5 id="242-密码杂凑函数">2.4.2 密码杂凑函数</h5>
            <h6 id="2421-密码杂凑函数h_v-">2.4.2.1 密码杂凑函数$H_v( )$</h6>
            <p>密码杂凑函数$H_v()$的输出是长度恰为v比特的杂凑值。本部分规定使用国家密码管理主管部门批准的密码杂凑函数，如SM3密码杂凑算法。</p>
            <h6 id="2422-密码杂凑函数h_1-">2.4.2.2 密码杂凑函数$H_1( )$</h6>
            <p>密码函数$H_1(Z,n)$的输入为比特串Z和整数n，输出为一个1到n-1的整数$h_1$，$H_1(Z,n)$需要调用密码杂凑函数$H_v()$。$H_v()$应符合本部分5.4.2.1的规定。</p>
            <h6 id="2423-密码杂凑函数h_2-">2.4.2.3 密码杂凑函数$H_2( )$</h6>
            <p>密码函数$H_2(Z,n)$的输入为比特串Z和整数n，输出为一个1到n-1的整数$h_2$，$H_2(Z,n)$需要调用密码杂凑函数$H_v()$。$H_v()$应符合本部分5.4.2.1的规定。</p>
            <h6 id="2423-随机数发生器">2.4.2.3 随机数发生器</h6>
            <p>本部分规定使用国家密码管理主管部门批准的随机数发生器。</p>
            <h3 id="3-数字签名生成算法及流程">3 数字签名生成算法及流程</h3>
            <h4 id="31-数字签名生成算法">3.1 数字签名生成算法</h4>
            <p>设待签名的消息为比特串M，为了获取消息M的数字签名$(h,S)$，作为签名者的用户A 应实现以下运算步骤：</p>

            <ol>
                <li>计算群$G_T$ 中的元素$g = e(P_1, P_{pub-s})$；</li>
                <li>产生随机数$r∈[1, N−1]$；</li>
                <li>计算群$G_T$ 中的元素$w=g_r$，将$w$的数据类型转换为比特串；</li>
                <li>
                    <table>
                        <tbody>
                        <tr>
                            <td>计算整数$h = H_2(M</td>
                            <td></td>
                            <td>w, N)$；</td>
                        </tr>
                        </tbody>
                    </table>
                </li>
                <li>计算整数$l = (r−h)$ mod $N$，若$l = 0$ 则返回$A_2$；</li>
                <li>计算群$G_1$ 中的元素$S = [l]d_sA$；</li>
                <li>消息$M$ 的签名为$(h, S)$。</li>
            </ol>

            <h4 id="32-数字签名生成算法流程">3.2 数字签名生成算法流程</h4>

            <h2 id="第3-部分密钥交换协议">第3 部分：密钥交换协议</h2>

            <h3 id="1-概述-1">1 概述</h3>
            <p>本部分规定了用椭圆曲线对实现的基于标识的密钥交换协议，并提供了相应的流程。该协议可以使
                通信双方通过对方的标识和自身的私钥经两次或可选三次信息传递过程，计算获取一个由双方共同决定
                的共享秘密密钥。该秘密密钥可作为对称密码算法的会话密钥。协议中选项可以实现密钥确认。</p>
            <h3 id="2-辅助函数">2 辅助函数</h3>
            <h4 id="21-概述-1">2.1 概述</h4>
            <p>基于标识的密钥交换协议中，涉及到三类辅助函数：密码杂凑函数、密钥派生函数、随机数发生器。这三类辅助函数的强弱直接影响密钥交换协议的安全性。</p>
            <h4 id="22-密码杂凑函数">2.2 密码杂凑函数</h4>
            <h5 id="221-密码杂凑函数h_v-">2.2.1 密码杂凑函数$H_v( )$</h5>
            <p>密码杂凑函数$H_v( )$的输出是长度恰为v比特的杂凑值。使用国家密码管理主管部门批准的密码杂凑函数，如SM3密码杂凑算法。</p>
            <h5 id="222-密码函数h_1-">2.2.2 密码函数$H_1( )$</h5>
            <p>
                密码函数$H_1(Z,n)$的输入为比特串$Z$和整数$n$，输出为一个$1$到$n-1$的整数$h_1$，$H_1(Z,n)$需要调用密码杂凑函数$H_v()$。$H_v()$应符合本部分5.4.2.1的规定。</p>
            <h5 id="223-密码函数h_2-">2.2.3 密码函数$H_2( )$</h5>
            <p>
                密码函数$H_2(Z,n)$的输入为比特串$Z$和整数$n$，输出为一个$1$到$n-1$的整数$h_2$，$H_2(Z,n)$需要调用密码杂凑函数$H_v()$。$H_v()$应符合本部分5.4.2.1的规定。</p>
            <h4 id="23-密钥派生函数kdfz-klen">2.3 密钥派生函数$KDF(Z, klen)$</h4>
            <p><strong>输入：</strong>
                共享比特串$Z$，整数$klen$</p>

            <p><strong>输出：</strong>
                长度为$klen$ 的密钥数据比特串$K$。</p>

            <p>
                密钥派生函数的作用是从一个共享的秘密比特串中派生出密钥数据。在密钥协商过程中，密钥派生函数作用在密钥交换所获共享的秘密比特串上，从中产生所需的会话密钥或进一步加密所需的密钥数据。密钥派生函数需要调用密码杂凑函数$H_v()$ </p>

            <h4 id="24-随机数发生器">2.4 随机数发生器</h4>
            <p>本部分规定使用国家密码管理主管部门批准的随机数发生器。</p>
            <h3 id="3-密钥交换协议及流程">3 密钥交换协议及流程</h3>
            <h4 id="31-密钥交换协议">3.1 密钥交换协议</h4>
            <p>设用户$A$ 和$B$ 协商获得密钥数据的长度为$klen$比特，用户$A$为发起方，用户$B$为响应方。用户$A$和$B$双方为了获得相同的密钥，应实现如下运算步骤：</p>

            <p><strong>用户A：</strong></p>

            <ol>
                <li>
                    <table>
                        <tbody>
                        <tr>
                            <td>计算群$G_1$ 中的元素$Q_B =[H_1(ID_B</td>
                            <td></td>
                            <td>hid, N)]P_1 +P_{pub-e}$；</td>
                        </tr>
                        </tbody>
                    </table>
                </li>
                <li>产生随机数$r_A∈[1, N]$;</li>
                <li>计算群$G_1$ 中的元素$R_A =[r_A]Q_B$；</li>
                <li>将$R_A$ 发送给用户$B$；</li>
            </ol>

            <p><strong>用户B：</strong></p>

            <ol>
                <li>
                    <table>
                        <tbody>
                        <tr>
                            <td>计算群$G_1$中的元素$Q_A=[H_1(ID_A</td>
                            <td></td>
                            <td>hid, N)]P_1 +P_{pub-e}$；</td>
                        </tr>
                        </tbody>
                    </table>
                </li>
                <li>产生随机数$r_B∈[1, N_1]$；</li>
                <li>计算群$G_1$中的元素$R_B =[r_B]Q_A$；</li>
                <li>
                    <p>验证$R_A∈G_1$是否成立，若不成立则协商失败；否则计算群$G_T$ 中的元素$g_1 = e(R_A, de_B)$，$g_2=e(
                        P_{pub-e},P_2)^{r_B}$，$g_3=g_1^{r_B}$，将$g_1$,$g_2$,$g_3$的数据类型转换为比特串；</p>
                </li>
                <li>
                    <table>
                        <tbody>
                        <tr>
                            <td>把$R_A$ 和$R_B$的数据类型转换为比特串，计算$SK_B=KDF(ID_A</td>
                            <td></td>
                            <td>ID_B</td>
                            <td></td>
                            <td>R_A</td>
                            <td></td>
                            <td>R_B</td>
                            <td></td>
                            <td>g_1</td>
                            <td></td>
                            <td>g_2</td>
                            <td></td>
                            <td>g_3, klen)$；</td>
                        </tr>
                        </tbody>
                    </table>
                </li>
                <li>
                    <table>
                        <tbody>
                        <tr>
                            <td>(选项)计算$SB=Hash(0x82</td>
                            <td></td>
                            <td>g_1</td>
                            <td></td>
                            <td>Hash(g_2</td>
                            <td></td>
                            <td>g_3</td>
                            <td></td>
                            <td>ID_A</td>
                            <td></td>
                            <td>ID_B</td>
                            <td></td>
                            <td>R_A</td>
                            <td></td>
                            <td>R_B))$；</td>
                        </tr>
                        </tbody>
                    </table>
                </li>
                <li>将$R_B$、(选项$S_B$)发送给用户$A$；</li>
            </ol>

            <p><strong>用户A：</strong></p>

            <ol>
                <li>
                    <p>验证$R_B∈G_1$ 是否成立，若不成立则协商失败；否则计算群T 中的元素$g_1’ =e( P_{pub-e},P_2)^{r_A}$，</p>

                    <p>$g_2’ = e(R_B, de_A)$，$g_3’ =(g_2’)^{r_A}$ ，将$g_1’$, $g_2’$, $g_3’$的数据类型转换为比特串；</p>
                </li>
                <li>
                    <p>把$RA$ 和$RB$的数据类型转换为比特串，(选项)计算</p>

                    <table>
                        <tbody>
                        <tr>
                            <td>$S_1=Hash(0x82</td>
                            <td></td>
                            <td>g_1’</td>
                            <td></td>
                            <td>Hash(g_2’</td>
                            <td></td>
                            <td>g_3’</td>
                            <td></td>
                            <td>ID_A</td>
                            <td></td>
                            <td>ID_B</td>
                            <td></td>
                            <td>R_A</td>
                            <td></td>
                            <td>R_B))$，并检验$S_1=S_B$是否成立，若等式不成立则从$B$到$A$的密钥确认失败；</td>
                        </tr>
                        </tbody>
                    </table>
                </li>
                <li>
                    <table>
                        <tbody>
                        <tr>
                            <td>计算$SK_A= KDF(ID_A</td>
                            <td></td>
                            <td>IDZ_B</td>
                            <td></td>
                            <td>R_A</td>
                            <td></td>
                            <td>R_B</td>
                            <td></td>
                            <td>g_1’</td>
                            <td></td>
                            <td>g_2’</td>
                            <td></td>
                            <td>g_3’, klen)$；</td>
                        </tr>
                        </tbody>
                    </table>
                </li>
                <li>
                    <table>
                        <tbody>
                        <tr>
                            <td>(选项)计算$S_A = Hash(0x83</td>
                            <td></td>
                            <td>g_1’</td>
                            <td></td>
                            <td>Hash(g_2’</td>
                            <td></td>
                            <td>g_3’</td>
                            <td></td>
                            <td>ID_A</td>
                            <td></td>
                            <td>ID_B</td>
                            <td></td>
                            <td>R_A</td>
                            <td></td>
                            <td>R_B))$，并将$S_A$ 发送给用户$B$。</td>
                        </tr>
                        </tbody>
                    </table>
                </li>
            </ol>

            <p><strong>用户B：</strong></p>

            <ol>
                <li>
                    <table>
                        <tbody>
                        <tr>
                            <td>(选项)计算$S_2=Hash(0x83</td>
                            <td></td>
                            <td>g_1</td>
                            <td></td>
                            <td>Hash(g_2</td>
                            <td></td>
                            <td>g_3</td>
                            <td></td>
                            <td>ID_A</td>
                            <td></td>
                            <td>ID_B</td>
                            <td></td>
                            <td>R_A</td>
                            <td></td>
                            <td>R_B))$，并检验$S_2=S_A$是否成立，若等式不成立则从$A$到$B$ 的密钥确认失败。</td>
                        </tr>
                        </tbody>
                    </table>
                </li>
            </ol>

            <h4 id="32-密钥交换流程">3.2 密钥交换流程</h4>

            <h2 id="第4-部分密钥交换协议">第4 部分：密钥交换协议</h2>

            <h3 id="1-算法参数与辅助函数">1 算法参数与辅助函数</h3>
            <h4 id="11-总则">1.1 总则</h4>

            <p>密钥封装机制为用椭圆曲线对实现的基于标识的密钥封装机制。解封装用户持有一个标识和一个相应的加密私钥，该加密私钥由密钥生成中心通过加密主私钥和解封装用户的标识结合产生。</p>

            <p>
                公钥加密算法为用椭圆曲线对实现的基于标识的公钥加密算法。该公钥加密算法是上述密钥封装机制和消息封装机制的结合，消息封装机制包括基于密钥派生函数的序列密码以及结合密钥派生函数的分组密码算法两种类型，该算法可提供消息的机密性。</p>

            <h4 id="12-系统加密主密钥和用户加密密钥的产生">1.2 系统加密主密钥和用户加密密钥的产生</h4>

            <p>KGC产生随机数$ke \in [1,
                N-1]$作为加密主私钥，计算$\mathbb{G}1$中的元素$P_{pub-e}=[e]P_{1}$作为加密主公钥，KGC秘密保存$ke$，公开$P_{pub-e}$。</p>

            <p>KGC选择并公开用一个字节表示的加密私钥生成函数识别符$hid$。</p>

            <p>KGC根据用户B的$ID_B$计算用户B的加密私钥$de_B$。KGC首先在有限域$F_N$上计算$t_1=H_1(ID_B\lVert hid,N)+ke$，若$t_1 =
                0$则需重新产生加密主私钥，计算和公开加密主公钥，并更新已有用户的加密私钥;否则计算。否则计算$t_2 = ke\cdot t_1^{-1}$，然后计算$de_B=[t_2]P_2$。</p>

            <h4 id="13-辅助函数">1.3 辅助函数</h4>

            <h5 id="131-密码杂凑函数h_v">1.3.1 密码杂凑函数$H_v()$</h5>
            <p>密码杂凑函数$H_v()$的输出是长度恰为$v$比特的杂凑值。规定使用国家密码管理主管部门批准 的密码杂凑函数，如SM3密码杂凑算法。</p>

            <h5 id="132-密码函数-h_1">1.3.2 密码函数 $H_1()$</h5>
            <p>密码函数$H_1(Z,n)$的输入为比特串$Z$和整数$n$，输出为一个整数$h_1 \in [1, n-1]$。 $H_1(Z,n)$需要调用密码杂凑函数$H_v()$。</p>

            <h5 id="133-密码函数-h_2">1.3.3 密码函数 $H_2()$</h5>
            <p>密码函数$H_2(Z,n)$的输入为比特串Z和整数n，输出为一个整数$h2 \in [1, n-1]$。$H_2(Z,n)$需要调用密码杂凑函数$H_v()$。</p>

            <h5 id="134-密钥派生函数">1.3.4 密钥派生函数</h5>
            <p>采用的密钥派生函数$KDF()$。</p>

            <h5 id="135-分组密码算法">1.3.5 分组密码算法</h5>
            <p>使用国家密码管理主管部门批准的分组密码算法，如SM4分组密码算法。</p>

            <h5 id="136-消息认证码函数">1.3.6 消息认证码函数</h5>
            <p>
                消息认证码函数$MAC(K2,Z)$的作用是防止消息数据$Z$被非法篡改，它在密钥$K_2$的控制下，产生消息数据比特串$Z$的认证码。在本基于标识的加密算法中，消息认证码函数使用密钥派生函数生成的密钥对密文比特串求取消息认证码，从而使解密者可以鉴别消息的来源和检验数据的完整性。消息认证码函数需要调用密码杂凑函数。</p>

            <h5 id="137-随机数发生器">1.3.7 随机数发生器</h5>
            <p>使用国家密码管理主管部门批准的随机数发生器。</p>

            <h3 id="2-密钥封装机制及流程">2 密钥封装机制及流程</h3>

            <h2 id="21-密钥封装算法">2.1 密钥封装算法</h2>

            <p>为了封装比特长度为klen的密钥给用户B，作为封装者的用户A需要执行以下运算步骤:</p>

            <ol>
                <li>计算群$\mathbb{G}1$中的元素$Q_B=[H_1(ID_B \lVert hid, N)]P_1+P_{pub-e}$;</li>
                <li>产生随机数$r \in [1, N-1]$;</li>
                <li>计算群$\mathbb{G}1$中的元素 $C=[r]Q_B$，将$C$的数据类型转换为比特串;</li>
                <li>计算群$\mathbb{G}T$中的元素$g=e(P_{pub-e},P_2)$;</li>
                <li>计算群$\mathbb{G}T$中的元素$w=g^r$，将w的数据类型转换为比特串;</li>
                <li>计算 $K=KDF(C \lVert w \lVert ID_B, klen)$，若$K$为全$0$比特串，则返回$A_2$。</li>
                <li>输出$(K, C)$，其中$K$是被封装的密钥，$C$是封装密文。</li>
            </ol>

            <h4 id="22-密钥封装算法流程">2.2 密钥封装算法流程</h4>

            <h4 id="23-解封装算法">2.3 解封装算法</h4>
            <p>用户B收到封装密文$C$后，为了对比特长度为$klen$的密钥解封装，需要执行以下运算步骤:</p>

            <ol>
                <li>验证$C \in \mathbb{G}1$是否成立，若不成立则报错并退出;</li>
                <li>计算群$\mathbb{G}T$中的元素$w’=e(C, de_B)$，将$w’$的数据类型转换为比特串;</li>
                <li>将$C$的数据类型转换为比特串，计算封装的密钥$K’=KDF(C\lVert w’\lVert ID_B, klen)$,若$K’$为全$0$比特串，则报错并退出;</li>
                <li>输出密钥$K’$。</li>
            </ol>

            <h4 id="24-解封装算法流程">2.4 解封装算法流程</h4>

            <h3 id="3-公钥加密算法及流程">3 公钥加密算法及流程</h3>
            <h4 id="31-加密算法">3.1 加密算法</h4>
            <p>设需要发送的消息为比特串$M$，$mlen$为$M$的比特长度，$K_1len$为分组密码算法中密钥K1的比特长度，$K_2len$为函数$MAC(K_2,Z)$中密钥$K_2$的比特长度。</p>

            <p>为了加密明文 $M$ 给用户 $B$，作为加密者的用户 $A$ 应实现以下运算步骤:</p>

            <ol>
                <li>计算群$\mathbb{G}1$中的元素$Q_B=[H_1(ID_B\lVert hid, N)]P_1+P_{pub-e}$;</li>
                <li>产生随机数$r \in [1, N-1]$;</li>
                <li>计算群$\mathbb{G}1$中的元素$C_1=[r]Q_B$，将$C_1$的数据类型转换为比特串;</li>
                <li>计算群$\mathbb{G}T$中的元素$g=e(P_{pub-e}, P_2)$;</li>
                <li>计算群$\mathbb{G}T$中的元素$w=g^r$，按将w的数据类型转换为比特串;</li>
                <li>按加密明文的方法分类进行计算:
                    <ol>
                        <li>如果加密明文的方法是基于密钥派生函数的序列密码算法，则
                            <ol>
                                <li>计算整数$klen=mlen+K_2len$，然后计算 $K=KDF(C_1\lVert w\lVert ID_B,
                                    klen)$。令$K_1$为$K$最左边的$mlen$比特，$K_2$为剩下的$K_2len$比特，若$K_1$为全0比特串，则返回 $A2$;
                                </li>
                                <li>计算 $C_2 = M \oplus K_1$。</li>
                            </ol>
                        </li>
                        <li>如果加密明文的方法是结合密钥派生函数的分组密码算法，则
                            <ol>
                                <li>计算整数$klen=K_1len + K_2len$，然后计算$K=KDF(C_1\lVert w\lVert ID_B,
                                    klen)$。令$K_1$为$K$最左边的$K_1len$比特，$K_2$为剩下的$K_2len$比特，若$K_1$为全$0$比特串，则返回A2;
                                </li>
                                <li>计算$C_2=Enc(K_1, M)$。</li>
                            </ol>
                        </li>
                    </ol>
                </li>
                <li>计算 $C_3=MAC(K_2, C_2)$;</li>
                <li>输出密文 $C=C_1\lVert C_3\lVert C_2$。</li>
            </ol>

            <h4 id="32-加密算法流程">3.2 加密算法流程</h4>

            <h4 id="33-解密算法">3.3 解密算法</h4>
            <p>设$mlen$为密文$C=C_1\lVert C_3\lVert C_2$中$C_2$的比特长度，$K_1len$为分组密码算法中密钥$K_1$的比特长度，$K_2len$为函数$MAC(K_2,
                Z)$中密钥$K_2$的比特长度。</p>

            <p>为了对 C 进行解密，作为解密者的用户 B 应实现以下运算步骤:</p>

            <ol>
                <li>从$C$中取出比特串$C_1$，将$C_1$的数据类型转换为椭圆曲线上的点，验证$C_1 \in G_1$是否成立，若不成立则报错并退出;</li>
                <li>计算群$\mathbb{G}T$中的元素$w’=e(C_1, de_B)$，将 $w’$的数据类型转换为比特串;</li>
                <li>按加密明文的方法分类进行计算:
                    <ol>
                        <li>如果加密明文的方法是基于密钥派生函数的序列密码算法，则
                            <ol>
                                <li>计算整数 $klen=mlen+K_2len$，然后计算 $K’=KDF(C_1\lVert w’\lVert ID_B, klen)$。令 $K1’$为
                                    $K’$最左边的$mlen$比特，$K_2’$为剩下的$K_2len$比特，若$K_1’$为全$0$比特串，则报错并退出;
                                </li>
                                <li>计算 $M’=C_2 \oplus K_1’$。</li>
                            </ol>
                        </li>
                        <li>如果加密明文的方法是结合密钥派生函数的分组密码算法，则
                            <ol>
                                <li>计算整数 $klen=K_1len+K_2len$，然后计算 $K’=KDF(C_1\lVert w’\lVert ID_B, klen)$。令
                                    $K_1’$为$K’$最左边的$K_1len$比特，$_2’$为剩下的$K_2len$比特，若 $K_1’$为全$0$比特串，则报错并退出;
                                </li>
                                <li>计算 $M’=Dec(K_1’, C_2)$。</li>
                            </ol>
                        </li>
                    </ol>
                </li>
                <li>计算$u=MAC(K_2’, C_2)$，从$C$中取出比特串$C_3$，若$u \neq C_3$，则报错并退出;</li>
                <li>输出明文$M’$。</li>
            </ol>

            <h4 id="34-解密算法流程">3.4 解密算法流程</h4>

            <h2 id="sm9的椭圆曲线参数-sm9s256t1">SM9的椭圆曲线参数 <code class="language-plaintext highlighter-rouge">sm9s256t1</code>
            </h2>

            <p>这里给出一个具备128位安全性的测试用SM9椭圆曲线参数参数<code class="language-plaintext highlighter-rouge">sm9s256t1</code>，其中椭圆曲线
                E: y^2 = x^3 + ax + b 定义在素数域F_p上，点G=(x,y)是曲线E上阶为n的点，p, n为素数。SM9参数(p, a, b, x, y, n)的16进制值如下：</p>

            <div class="language-plaintext highlighter-rouge">
                <div class="highlight"><pre class="highlight"><code>p = 0xab64be0955a39254a6cfe231531c02ebc0cd4c307800c7eb49fabcc179174e0400365f7280d166bf67839bba4047bab1212f2966d3045dcfc08d83d57fb7d01b6f958e077caeba969057287a8ea75c93660747c68c32af9c874bfd87d1a40c9aa709813930f3e7d7d794874146eceb73a14cfc41cfad0007fc30ead26f938349a017115a506c49dfb78002ccffaed045b39bc8970756c275d484f60dc7ba609f8dfe7142f8dfac81cc53a6bd67e1dcc18f35aad88a94ee40dd90934a282203cb
a = 0
b = 1
x = 0x6613bde4d70b02a29a1700d2063420e408b0c23c85fdfca2b37df38b872492f191dda03d4c520be9dced93d8678c5a898a9e81ddddb6afc9fa882e808fb48e33bd3e08756db0db2b271e82c48139d6b048edffd7736b0aca63f8733c2134ab7e0b33f11a0e61b89bd7259b752b24ada949b958f95d2c914b34e29a6ee888acc604ab0d0818fc2ab09546db9eab4a452909ce88298abc644678f8b9ecbee7eb334ffe4c25a8d5fcd7dd4b74d0362033acacd3cd363f22ab2a76605fdc8868654b
y = 0x117ff162e1e4a92fc920677f84a2b9ab151f3545f5094f6471d8d02d47bd8b7eb09e4ef771710be64809442ee66965406f6a55d317a8dde231d257f5fc2e84bf99e3077e9f53cb49e8c6d792437cb1b525ea7e83594b2928e72db64349619fb47392759c9909f7ccd9d7d54b2605969ed59875a39a99e6914404d17d4f5a8ba2d7486aa36ee235dcdc4385a292348c4de9373d4cae3fcb07297aef083dc04f10d25efb6b60d116d0b95151a3ff96a2eaee556bbac0ad6b6633dfd1c1d5c896e2
n = 0xffffffffffffffffffffff000000000000000000000000000000000000000001
h = 0xab64be0955a39254a6cfe2dcb7da0c41645fa0d747e3a4a32406fe25d8b8254b3876448d322bfa4378d90415feb23ba1e8c9cc086424cf2b4ec2279870cbb3345bee74c90caa58c3e33158c07e69e9fe27963fa15966a0efa273d416f717fabfb1bbfc12981da60b0c5dee32847f140d975cc7acd434919cd8d12452d543355e22ecb2208972f6a9ee5772bd67e1dcc18f35aad88a94ee40dd90934a282203cc
</code></pre>
                </div>
            </div>

            <div class="language-plaintext highlighter-rouge">
                <div class="highlight"><pre class="highlight"><code>m = 0x72bfbd857cc548bd585804498be4214d3c772d373918eac2c0ca968620f559d60d1c3cf341de03ab5c9123659ce7b3ee3e05a01755ad0b8bf795382fbdbbc3ddf6b199f5fb30bccf0825a9fd856629e63ca5aac6f88b0e9b36996b00a3bfba6b5a921f573d0024167220b833d6a24777eada3bdbeb8f12107d1aa435a544dd67572dd7e696a93155a65d2c4c2e5563a2751b939ab5426fa61ca6f23d7b4ad3fbef8231330c73a404c8ea2a5ad7a5680117286102e12fac42c917bb19d832e2f2c35e64c1a2a44e467391d696860b2cadc9871d0daeb7e6655fdf03b0c30a7373615216d1f2624c630b15e8ee2b9ea44bc424b12013654cc4df0654fbc16ebd4b9fb8c290a384c4ec265e036ab9524802d947eb314054fc977c7ea13f9145ef5e0743f2385c5f9ce9d72566685b5d5c3459b5e5f35a8d1baccda6a43458109d91a6ab32ed246c2b038e1da90703630337dd6b8da2a03d79e30caff91071fa62f8
z0 = 0x55b25f04aad1c92a5367f118a98e0175e066a6183c0063f5a4fd5e60bc8ba702001b2fb94068b35fb3c1cddd2023dd58909794b369822ee7e046c1eabfdbe80db7cac703be575d4b482b943d4753ae49b303a3e3461957ce43a5fec3e8d2064d5384c09c9879f3ebebca43a0a37675b9d0a67e20e7d68003fe18756937c9c1a4d00b88ad283624efdbc001667fd76822d9cde44b83ab613aea427b06e3dd304fc6ff38a17c6fd640e629d35eb3f0ee60c79ad56c454a77206ec849a5141101e5
z1 =0x1ad2eed923bea051a743b4a2dfbeb5f1f1d641eb09fc060c6aec8e810f2acea9b3cccd140afecebfe383a09bff48a85bcbe2b9c887d9d4bf57d18b81709ada159e304b7fab6d375ff1f6e21f34ff2418ccfe40f8fdf9deb71f951245d9a2618b36718554eb836d552b7ab13541fcb7a0fec60da978f2008835caae21c288aa3e921b4a7605eba8c4d482d95b2fa1b4d2e41550a9d1305e954f438c2424ef559fe7ba606069b4f074143d21a9f8e79257d3631daea4d9cedb3acd314194fe83ae
</code></pre>
                </div>
            </div>

        </section>
    </div>
</template>

<script>
    export default {
        name: "sm9-doc"
    }
</script>

<style scoped lang="less">
    @import "style.less";
</style>
